#include <linux/fs.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/delay.h>
#include <linux/uaccess.h>
#include <linux/io.h>
#include <linux/cdev.h>
#include <linux/gpio.h>
#include <linux/list.h>
#include <linux/slab.h>
#include <linux/i2c.h>
#include <linux/err.h>
#include <linux/kernel.h>
#include <linux/device.h>
#include <linux/delay.h>
#include <linux/platform_device.h>
#include <linux/of_address.h>
#include <linux/regulator/driver.h>
#include <linux/regulator/machine.h>
#include <linux/regulator/consumer.h>


static void virt_consumer_dev_release(struct device *dev)
{

}

static struct platform_device virt_consumer_platform_device = {
	.name = "virt_consumer01",
	.id = -1,
	.dev = {
		/*.platform_data = &virt_gpio_data,*/
		.release = virt_consumer_dev_release,
	}
};

struct virt_consumer_dev
{
	struct regulator *regulator;
	int vref_sel;
};
static int virt_consumer_platform_probe(struct platform_device *platform_dev)
{
	struct virt_consumer_dev *devp = NULL;
	int ret = 0;

	devp =  devm_kzalloc(&platform_dev->dev, sizeof(*devp), GFP_KERNEL);
	if(devp == NULL)
		return -ENOMEM;
	devp->regulator = regulator_get(&platform_dev->dev, "virt-vcc");
	if(!IS_ERR(devp->regulator))
	{
		ret = regulator_enable(devp->regulator);
		if (ret) 
		{
			goto free_regulator;
		}
		
		ret = regulator_get_voltage(devp->regulator);
		if (ret < 0)
			goto disable_regulator;

		devp->vref_sel = ret;
		ret = 0;
	}
	platform_set_drvdata(platform_dev, devp);

	return ret;
	
disable_regulator:
	regulator_disable(devp->regulator);

free_regulator:
	if (!IS_ERR(devp->regulator))
		regulator_put(devp->regulator);

	return ret;
}

static int virt_consumer_platform_remove(struct platform_device *platform_dev)
{
	int ret = 0;
	struct virt_consumer_dev *devp = platform_get_drvdata(platform_dev);

	printk("%s:%d\n", __FUNCTION__, __LINE__);
	if (!IS_ERR(devp->regulator)) 
	{
		regulator_disable(devp->regulator);
		regulator_put(devp->regulator);
	}

	return ret;
}

static struct platform_driver virt_consumer_platform_driver = {
	.driver = {
		.name = "virt_consumer01",
		.owner = THIS_MODULE,
	},
	.probe = virt_consumer_platform_probe,
	.remove = virt_consumer_platform_remove,
};

static int __init virt_consumer_platform_init(void)
{
	int ret = 0;

	ret = platform_device_register(&virt_consumer_platform_device);
	if(ret == 0)
	{
		ret = platform_driver_register(&virt_consumer_platform_driver);
	}

	return ret;
}
static void __exit virt_consumer_platform_exit(void)
{
	platform_device_unregister(&virt_consumer_platform_device);
	
	platform_driver_unregister(&virt_consumer_platform_driver);
}


module_init(virt_consumer_platform_init);
module_exit(virt_consumer_platform_exit);
MODULE_DESCRIPTION("Virtual Regulator Consumer Platform Device");
MODULE_LICENSE("GPL");
MODULE_AUTHOR("jerry_chg");
